/**
 * @notice artifacts.require指定我们想要测试的合约，此时Truffle就会自动提供由我们的智能合约产生的日志
 */
const MyToken = artifacts.require("MyToken");
const utils = require("./utils/utils");

contract("MyToken", (accounts) => {
  // 模拟两个地址
  let [alice, bob] = accounts;
  let contractInstance;

  beforeEach(async () => {
    /**
     * @notice 实例化合约对象
     * @dev 合约实例化时，若不指定部署账户，则默认使用第一个账户
     */
    contractInstance = await MyToken.new("WarrickToken", "WKT", { from: bob });
  });

  // it()函数的第二个参数是一个callback回调函数
  it("contract creator bob should have 1000000 WKT, another should be 0 WKT", async () => {
    const bobBalance = await contractInstance.balanceOf(bob);
    assert.equal(web3.utils.fromWei(bobBalance, "ether"), 1000000);
    const aliceBalance = await contractInstance.balanceOf(alice);
    assert.equal(aliceBalance, 0);
  });

  it("bob transfer 100 KWT to alice", async () => {
    await contractInstance.transfer(alice, web3.utils.toWei("100", "ether"), {
      from: bob,
    });
    const bobBalance = await contractInstance.balanceOf(bob);
    assert.equal(web3.utils.fromWei(bobBalance, "ether"), 999900);
    const aliceBalance = await contractInstance.balanceOf(alice);
    assert.equal(web3.utils.fromWei(aliceBalance, "ether"), 100);
  });

  // context函数用于隔离不同的测试单元
  context("with the two-step transfer WKT", async () => {
    it("alice transfer 100 WKT that bob approved to his account", async () => {
      const result = await contractInstance.approve(
        alice,
        web3.utils.toWei("100", "ether"),
        {
          from: bob,
        }
      );
      // result交易处理对象
      assert.equal(result.receipt.status, true);
      assert.equal(result.logs[0].args._owner, bob);

      await contractInstance.transferFrom(
        bob,
        alice,
        web3.utils.toWei("100", "ether")
      );
      const aliceBalance = await contractInstance.balanceOf(alice);
      assert.equal(web3.utils.fromWei(aliceBalance, "ether"), 100);
    });

    it("alice transfer WKT that bob don't approve should be throw an error", async () => {
      await utils.shouldThrow(
        contractInstance.transferFrom(
          bob,
          alice,
          web3.utils.toWei("100", "ether")
        )
      );
    });
  });
});
